package icu.twtool.entity

import kotlin.math.max
import kotlin.math.min

/**
 * 算式数据结构
 */
abstract class BinaryEquation(
    /**
    * 第一个操作数
    */
    val first: Int,

    /**
    * 第二个操作数
    */
    val second: Int,

    /**
    * 操作数的最长长度
    */
    private val len: Int
) {

    /**
     * 操作符
     */
    abstract val operation: Char

    /**
     * 将算式转换为字符串
     */
    fun toString(answer: Boolean = false): String {
        val answerStr = if (answer) "%${len}d" else "%${len}s".format("")
        return "%${len}d %c %${len}d = $answerStr".format(first, operation, second, answer())
    }

    /**
     * 将算式转换为字符串
     */
    override fun toString(): String {
        return toString(true)
    }

    /**
     * 计算算式的答案
     */
    abstract fun answer(): Int

    /**
     * 比较两个算式是否相等
     */
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as BinaryEquation

        return this.hashCode() == other.hashCode()
    }

    /**
     * 计算算式的 hashCode 值
     */
    override fun hashCode(): Int {
        var result = min(first, second)
        result = 31 * result + max(first, second)
        result = 31 * result + operation.hashCode()
        return result
    }

    companion object {

        /**
         * 算式的正则表达式
         */
        val REGEX = Regex("(\\d+)\\s*(.)\\s*(\\d+)\\s*=\\s*")
    }

}